home *** CD-ROM | disk | FTP | other *** search
- #define __USE_SYSBASE
-
- #include <exec/execbase.h>
- #include <exec/memory.h>
- #include <dos/exall.h>
- #include <libraries/utgui.h>
- #include <clib/exec_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/utgui_protos.h>
- #include <clib/alib_protos.h>
- #include <pragmas/exec_pragmas.h>
- #include <pragmas/dos_pragmas.h>
- #include <pragmas/utgui_pragmas.h>
- #include <string.h>
- #include <stdlib.h>
-
- #define BUFSIZE 2000
-
- static UBYTE *version_string = "$VER: DupFinder 1.0 (24.4.95)";
-
- UBYTE *template = "PATH/A/M,NAMES/S,MINSIZE=MIN/N,NOICONS=NOINFO/S,PRI/N";
-
- enum {
- PATH,
- NAMES,
- MINSIZE,
- NOICONS,
- PRI,
- NUM_ARGS
- };
-
- typedef struct l {
- BPTR dir;
- struct ExAllControl *eac;
- struct ExAllData *entry;
- struct l *next;
- } list;
-
- extern void * __asm AsmCreatePool(register __d0 ULONG, register __d1 ULONG, register __d2 ULONG, register __a6 struct ExecBase *);
- extern void __asm AsmDeletePool(register __a0 void *, register __a6 struct ExecBase *);
- extern void * __asm AsmAllocPooled(register __a0 void *, register __d0 ULONG, register __a6 struct ExecBase *);
- extern void __asm AsmFreePooled(register __a0 void *, register __a1 void *, register __d0 ULONG, register __a6 struct ExecBase *);
-
- UWORD exall(struct ExecBase *SysBase, struct DosLibrary *DOSBase, list **myold, char *path, ULONG *numfiles, void *pool);
- __inline BOOL compare(BOOL first, BPTR thisdir, struct ExAllData *this, BPTR otherdir, struct ExAllData *other, LONG *arg_array, struct DosLibrary *DOSBase, struct ExecBase *SysBase, void *pool);
-
- int __saveds main(void)
- {
- struct ExecBase *SysBase = *(struct ExecBase **)4L;
- struct RDArgs *rdargs=NULL;
- LONG arg_array[NUM_ARGS];
- struct DosLibrary *DOSBase = (struct DosLibrary *)OpenLibrary(DOSNAME, 37L);
- struct Library *UTGuiBase = OpenLibrary("utgui.library", 1L);
- struct ExAllData *this, *other;
- list *mylist, *mynew, *myold;
- char **trav; //, this_string[256], other_string[256];
- void *pool;
- UWORD ret;
- APTR progbar = NULL;
- ULONG files = 0L, filenum;
- LONG oldpri=256;
- BOOL first;
-
- if(!DOSBase) return(20L);
-
- if(!(pool = AsmCreatePool(MEMF_ANY, 10240, 5120, SysBase)))
- goto quit;
-
- if(!(mylist = myold = AsmAllocPooled(pool, sizeof(list), SysBase))) goto quit;
- mylist->next = NULL;
- mylist->entry = NULL;
- memset(arg_array, 0, sizeof(LONG)*NUM_ARGS);
- if(!(rdargs = ReadArgs(template, arg_array, NULL))){
- Printf("Usage: dupfinder <path1> [<path2> ...] [names] [minsize=<bytes>]\n"
- " [noicons] [pri=<priority>]\n");
- goto quit;
- }
-
- if(arg_array[PRI])
- oldpri = SetTaskPri(FindTask(0), *(LONG *)arg_array[PRI]);
-
- for(trav = (char **)arg_array[PATH];*trav;trav++){
- if(ret = exall(SysBase, DOSBase, &myold, *trav, &files, pool)){
- if(ret != 2)
- Printf("ExAll() failed\n");
- goto quit;
- }
- }
-
- if(UTGuiBase)
- progbar = ugOpenProgressBar("DupFinder", PB_ProgressText, "Comparing files...", PB_Total, files, PB_InactiveWin, TRUE, TAG_DONE);
-
- for(mynew = mylist->next, filenum = 0; mynew; mynew = mynew->next){
- for(this = mynew->entry; this; this=this->ed_Next, ++filenum){
- first = TRUE;
- if(progbar)
- ugUpdateProgressBar(progbar, PB_Current, filenum, TAG_DONE);
- if(this->ed_Next) other = this->ed_Next;
- else if(mynew->next) other = (mynew->next)->entry;
- else break;
- myold = mynew;
- for(;; other->ed_Next ? (other = other->ed_Next)
- : (myold->next ? (other = (myold = myold->next)->entry)
- : (other = NULL))){
- if(!other) break;
- if(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C){
- Printf("***Break\n");
- goto quit;
- }
- if(compare(first, mynew->dir, this, myold->dir, other, arg_array, DOSBase,
- SysBase, pool)) first = FALSE;
- }
- if(!first) Printf("\n");
- }
- }
-
- quit:
- if(progbar)
- ugCloseProgressBar(progbar);
-
- for(myold = mynew = mylist; myold; myold=mynew){
- if(mynew) mynew=mynew->next;
- if(myold != mylist && myold->eac){
- FreeDosObject(DOS_EXALLCONTROL, myold->eac);
- UnLock(myold->dir);
- }
- }
- AsmDeletePool(pool, SysBase);
- if(oldpri!=256) SetTaskPri(FindTask(0), oldpri);
- if(rdargs) FreeArgs(rdargs);
- CloseLibrary(UTGuiBase);
- CloseLibrary((struct Library *)DOSBase);
- return(0L);
- }
-
-
- UWORD exall(struct ExecBase *SysBase, struct DosLibrary *DOSBase, list **myold, char *path, ULONG *numfiles, void *pool)
- {
- list *mynew;
- int more;
- char *buffer, *nfl_buf;
- struct ExAllData *entry;
- BPTR mylock;
- struct ExAllControl *eac;
- BOOL first=TRUE, broken=FALSE;
- UWORD ret;
-
- if(!(mylock = Lock(path, ACCESS_READ))){
- Printf("Can't lock \"%s\".\n", path);
- return(1);
- }
-
- if(!(eac = AllocDosObject(DOS_EXALLCONTROL, NULL))){
- UnLock(mylock);
- return(1);
- }
- eac->eac_LastKey = 0;
- do {
- if(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C){
- if(DOSBase->dl_lib.lib_Version >= 39){
- Printf("***Break\n");
- UnLock(mylock);
- FreeDosObject(DOS_EXALLCONTROL, eac);
- return(2);
- }
- else broken = TRUE;
- }
- if(buffer = AsmAllocPooled(pool, BUFSIZE, SysBase))
- more = ExAll(mylock, (struct ExAllData *)buffer, BUFSIZE, ED_SIZE, eac);
- if(!buffer || (!more && (IoErr() !=ERROR_NO_MORE_ENTRIES))){
- FreeDosObject(DOS_EXALLCONTROL, eac);
- UnLock(mylock);
- return(1); // Something seriously wrong.
- }
- if(eac->eac_Entries==0){
- FreeDosObject(DOS_EXALLCONTROL, eac);
- UnLock(mylock);
- return(0);
- }
- *numfiles += eac->eac_Entries;
-
- if(!(mynew = AsmAllocPooled(pool, sizeof(list), SysBase))){
- FreeDosObject(DOS_EXALLCONTROL, eac);
- UnLock(mylock);
- return(1);
- }
- memset(mynew, 0, sizeof(list));
- (*myold)->next = mynew;
- if(first) mynew->eac = eac;
- first = FALSE;
- mynew->entry = (struct ExAllData *) buffer;
- mynew->dir = mylock;
- *myold = mynew;
-
- if(!broken && (nfl_buf = AsmAllocPooled(pool, 256, SysBase))){
- for(entry = mynew->entry; entry; entry=entry->ed_Next)
- if(entry->ed_Type == ST_USERDIR){
- NameFromLock(mylock, nfl_buf, 255);
- AddPart(nfl_buf, entry->ed_Name, 255);
- if(ret = exall(SysBase, DOSBase, myold, nfl_buf, numfiles, pool)){
- if(ret != 2)
- Printf("Couldn't check \"%s\"\n", nfl_buf);
- AsmFreePooled(pool, nfl_buf, 256, SysBase);
- return(ret);
- }
- }
- AsmFreePooled(pool, nfl_buf, 256, SysBase);
- }
- } while(more);
- if(broken){
- Printf("***Break\n");
- return(2);
- }
- return(0);
- }
-
- #define BSIZE 32768
-
- __inline BOOL compare(BOOL first, BPTR thisdir, struct ExAllData *this, BPTR otherdir,
- struct ExAllData *other, LONG *arg_array,
- struct DosLibrary *DOSBase, struct ExecBase *SysBase, void *pool)
- {
- char other_string[256], this_string[256];
- static char *other_buffer = NULL, *this_buffer = NULL;
- int actual = this->ed_Size, bsize = 512;
- BPTR fh_this, fh_other;
-
- // Compare files
- if(this->ed_Type!=ST_FILE
- || !this->ed_Size
- || (!arg_array[NAMES] && this->ed_Size != other->ed_Size)
- || (arg_array[MINSIZE] ? (this->ed_Size < *(LONG *)arg_array[MINSIZE]) : FALSE))
- return(FALSE);
-
- if(this->ed_Size != other->ed_Size){
- if(!stricmp(this->ed_Name, other->ed_Name)){
- NameFromLock(thisdir, this_string, 255);
- AddPart(this_string, this->ed_Name, 255);
- NameFromLock(otherdir, other_string, 255);
- AddPart(other_string, other->ed_Name, 255);
- if(!strcmp(this_string, other_string)) return(FALSE);
- if(first) Printf("\"%s\" ;identical to\n\"%s\" ;name only\n",
- this_string, other_string);
- else Printf("\"%s\" ;name only\n", other_string);
- return(TRUE);
- }
- return(FALSE);
- }
-
- NameFromLock(thisdir, this_string, 255);
- AddPart(this_string, this->ed_Name, 255);
- NameFromLock(otherdir, other_string, 255);
- AddPart(other_string, other->ed_Name, 255);
-
- if(!strcmp(this_string, other_string)) return(FALSE);
-
- if(arg_array[NOICONS] && (strlen(this_string)>5
- && !stricmp(&this_string[strlen(this_string)-5], ".info")))
- return(FALSE);
-
- if(!(fh_this = Open(this_string, MODE_OLDFILE))){
- Printf("Can't open \"%s\".\n", this_string);
- return(FALSE);
- }
- if(!(fh_other = Open(other_string, MODE_OLDFILE))){
- Printf("Can't open \"%s\".\n", other_string);
- Close(fh_this);
- return(FALSE);
- }
-
- if(!this_buffer)
- if(!(this_buffer = AsmAllocPooled(pool, BSIZE, SysBase))){
- PutStr("Out of memory.\n");
- return(FALSE);
- }
- if(!other_buffer)
- if(!(other_buffer = AsmAllocPooled(pool, BSIZE, SysBase))){
- PutStr("Out of memory.\n");
- return(FALSE);
- }
-
- while(actual>0){
- if(Read(fh_this, this_buffer, bsize)!=-1){
- if(Read(fh_other, other_buffer, bsize)!=-1){
- if(memcmp(this_buffer, other_buffer, (actual<bsize) ? actual : bsize)){
- Close(fh_other);
- Close(fh_this);
- if(arg_array[NAMES] && !strcmp(this->ed_Name, other->ed_Name)){
- if(first) Printf("\"%s\" ;identical to\n\"%s\" ;name only\n",
- this_string, other_string);
- else Printf("\"%s\" ;name only\n", other_string);
- return(TRUE);
- }
- return(FALSE);
- }
- } else {
- Printf("Error reading from \"%s\" (error: %ld)\n", other_string, IoErr());
- Close(fh_other);
- Close(fh_this);
- return(FALSE);
- }
- } else {
- Printf("Error reading from \"%s\" (error: %ld)\n", this_string, IoErr());
- Close(fh_other);
- Close(fh_this);
- return(FALSE);
- }
- actual-=bsize;
- bsize = BSIZE;
- }
- if(first) Printf("\"%s\" ;identical to\n\"%s\"\n", this_string, other_string);
- else Printf("\"%s\"\n", other_string);
- other->ed_Type = ~ST_FILE;
- Close(fh_other);
- Close(fh_this);
- return(TRUE);
- }
-